/** \file emu.h
 *
 * Private header for Blackfin emulation functions
 *
 * (c) 11/2004 Martin Strubel <hackfin@section5.ch>
 *
 * $Id: emu.h 75 2005-11-11 09:12:34Z jiez $
 *
 */
#ifndef _EMU_H
#define _EMU_H

#include "platform.h" // platform specific defines

#include "jtag.h"
#ifdef USE_FTDI
#	define JTAG_CTRL CONTROLLER
#else // use JTAG tools
#	include "tap.h"
#	include "state.h"
#	define JTAG_CTRL chain_t *
#endif


// Top level API header:
#include "bfemu.h"

#include "bfin-registers.h"

// Watchpoint unit
//
// #ifndef WPIACTL
// #define WPIACTL          0xffe07000
// #endif
#	define  WPAND        0x02000000
#	define  EMUSW5       0x01000000
#	define  EMUSW4       0x00800000
#	define  WPICNTEN5    0x00400000
#	define  WPICNTEN4    0x00200000
#	define  WPIAEN5      0x00100000
#	define  WPIAEN4      0x00080000
#	define  WPIRINV45    0x00040000
#	define  WPIREN45     0x00020000
#	define  EMUSW3       0x00010000
#	define  EMUSW2       0x00008000
#	define  WPICNTEN3    0x00004000
#	define  WPICNTEN2    0x00002000
#	define  WPIAEN3      0x00001000
#	define  WPIAEN2      0x00000800
#	define  WPIRINV23    0x00000400
#	define  WPIREN23     0x00000200
#	define  EMUSW1       0x00000100
#	define  EMUSW0       0x00000080
#	define  WPICNTEN1    0x00000040
#	define  WPICNTEN0    0x00000020
#	define  WPIAEN1      0x00000010
#	define  WPIAEN0      0x00000008
#	define  WPIRINV01    0x00000004
#	define  WPIREN01     0x00000002
#	define  WPPWR        0x00000001

// #ifndef WPDACTL
// #define WPDACTL          0xffe07100
// #endif
#	define WPDACC1(x)   (((x) << 12) & 0x00003000 )
#	define WPDSRC1(x)   (((x) << 10) & 0x00000c00 )
#	define WPDACC0(x)   (((x) << 8) & 0x00000300 )
#	define WPDSRC0(x)   (((x) << 6) & 0x000000c0 )
#		define WPDACC_W         0x1
#		define WPDACC_R         0x2
#	define WPDCNTEN1     0x00000020
#	define WPDCNTEN0     0x00000010
#	define WPDAEN1       0x00000008
#	define WPDAEN0       0x00000004
#	define WPDRINV01     0x00000002
#	define WPDREN01      0x00000001


// #ifndef WPSTAT



#define MEM_SDRAM        0x00000000   // Beginning of SDRAM
#define MEM_SDRAM_E      0x08000000   // End of SDRAM
#define MEM_ASYNC        0x20000000   // Beginning of Async RAM banks
#define MEM_ASYNC_E      0x20400000   // End of Async RAM banks
#define MEM_L1_INSTR     0xffa00000   // Beginning of instruction SRAM
#define MEM_L1_INSTR_E   0xffa14000   // End of instruction SRAM/Cache
#define MEM_L1_SCRATCH   0xffb00000   // Beginning of L1 ScratchPad
#define MEM_L1_SCRATCH_E 0xffb01000   // End of L1 ScratchPad
#define MEM_MMR          0xffc00000   // Beginning of System MMR map


// This is the temporary data buffer for DMA access to L1CODE SRAM
#define DATA_BUF                    0xff800000

#define BFIN_REGISTER_WIDTH    32
#define DBGCTL_TYPE    unsigned short

#define BFIN_CACHELINE_BYTES	32

// DEBUG (EMULATION) CONTROL BIT DEFINITIONS

#define DBGCTL_EMPWR                    0x0001
#define DBGCTL_EMFEN                    0x0002
#define DBGCTL_EMEEN                    0x0004
#define DBGCTL_EMPEN                    0x0008
#define DBGCTL_EMUIRSZ                  0x0030
#define DBGCTL_EMUIRLPSZ                0x0040
#define DBGCTL_EMUDATSZ                 0x0180
#define DBGCTL_ESSTEP                   0x0200
#define DBGCTL_SYSRST                   0x0400
#define DBGCTL_WAKEUP                   0x0800
#define DBGCTL_SRAM_INIT                0x1000


/*
 * Simple instructions:
 */

#define INS_NOP			0x00000000
#define INS_RTE			0x00140000
#define INS_RESET		0x00910000  // 'raise 1'
#define INS_CSYNC		0x00230000
#define INS_SSYNC		0x00240000
#define INS_IFLUSH_P0		0x02580000  // iflush[p0]
#define INS_IFLUSH_P0_PP	0x02780000  // iflush[p0++]
#define INS_FLUSH_P0		0x02500000  // flush[p0]
#define INS_FLUSH_P0_PP		0x02700000  // flush[p0++]

/*
 * Blackfin 53x scan chain definitions
 */

#define SCAN_IDCODE  0x02
#define SCAN_DBGCTL  0x04
#define SCAN_DBGSTAT 0x0c
#define SCAN_EMUIR   0x08
#define SCAN_EMUDAT  0x14
#define SCAN_EMUPC   0x1e

/* 
 * The Blackfin CPU host proxy structure
 */

typedef struct _cpu {
	JTAG_CTRL      controller;
	CpuState       state;
	unsigned long  flags;
	unsigned long  id;
	unsigned long  mdma0_base;   // MDMA MMR base, CPU dependent!
	DBGCTL_TYPE    dbgctl;
	BFIN_REGISTER  wpiactl;      // instruction address watchpoint control
	BFIN_REGISTER  wpdactl;      // data watchpoint control
} Cpu;

////////////////////////////////////////////////////////////////////////////
// PROTOS

void          m_sleep(int value);

int           jtag_open(char * const *argv, JTAG_CTRL *c);

void          jtag_close(JTAG_CTRL c);

void          jtagchain_select(JTAG_CTRL c);

int           get_memory_word(ADDR addr, unsigned long *word, int size);

int           set_memory_word(ADDR addr, unsigned long word, int size);

int           init_dma(CPU cpu, ADDR dst, ADDR src, unsigned short count);

////////////////////////////////////////////////////////////////////////////
// DEBUGGING

int gettime(TIMEVAL *t);
float took_time(TIMEVAL *t0, TIMEVAL *t1);

#ifdef DEBUG
#define DEB(x) (x)
#else
#define DEB(x)
#endif

#endif
